﻿using System.Collections.ObjectModel;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace HMEngine.HMInputs {
    public delegate void HMKeyPressedHandler(Collection<Keys> keys);

    public delegate void HMKeyHeldHandler(Collection<Keys> keys);

    public delegate void HMKeyReleasedHandler(Collection<Keys> keys);

    public sealed class HMKeyboardDevice : HMInputDevice {
        private Collection<Keys> lastPressedKeys;
        private KeyboardState lastState;

        private Collection<Keys> pressed;
        private Collection<Keys> held;
        private Collection<Keys> released;

        public event HMKeyPressedHandler OnKeyPressed;
        public event HMKeyHeldHandler OnKeyHeld;
        public event HMKeyReleasedHandler OnKeyReleased;

        public override void Initialize() { lastState = Keyboard.GetState(); }

        public override void Update(GameTime gameTime) {
            KeyboardState currentState = Keyboard.GetState();
            var currentPressedKeys = new Collection<Keys>(currentState.GetPressedKeys());
            lastPressedKeys = new Collection<Keys>(lastState.GetPressedKeys());
            lastState = currentState;

            pressed = new Collection<Keys>();
            held = new Collection<Keys>();
            released = new Collection<Keys>();

            // Loading Event Lists
            foreach (Keys key in currentPressedKeys) {
                if (lastPressedKeys.Contains(key)) {
                    held.Add(key);
                } else {
                    pressed.Add(key);
                }
            }
            foreach (Keys key in lastPressedKeys) {
                if (!currentPressedKeys.Contains(key)) {
                    released.Add(key);
                }
            }

            // Event Calls
            if (pressed.Count > 0 && null != OnKeyPressed) {
                OnKeyPressed(pressed);
            }
            if (held.Count > 0 && null != OnKeyHeld) {
                OnKeyHeld(held);
            }
            if (released.Count > 0 && null != OnKeyReleased) {
                OnKeyReleased(released);
            }
        }

        public override void Dispose() { }
    }
}